/*
 * Copyright (C), 2010-2023, ATCOM Tech. Co., Ltd.
 *
 * File Name: libtest1.c
 * Author: liaoxuecheng
 * mail: liaoxuecheng@atcom.com.cn
 * Created Time: 2024年10月10日 星期四 14时02分12秒
 *
 */

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include <unistd.h>
#include <sys/syscall.h>

#define THIS_FILE "libtest1.c"

#define LINE_STR(a) #a
#define STR_LINE(a) LINE_STR(a)

__asm__(
#ifdef __LP64__
        "syscall: mov    %rdi,%rax;"
        "   mov    %rsi,%rdi;"
        "   mov    %rdx,%rsi;"
        "   mov    %rcx,%rdx;"
        "   mov    %r8,%r10;"
        "   mov    %r9,%r8;"
        "   mov    0x8(%rsp),%r9;"
        "   syscall;"
        "   cmp    $0xfffffffffffff001,%rax;"
        "   jae    __syscall_error;"
        "   retq;   "
        "__syscall_error: neg    %rax;"
        "   mov    %eax,%fs:0xffffffffffffffd0;"
        "   or     $0xffffffffffffffff,%rax;"
        "   retq;"   
#else
        "syscall:   push   %ebp;"
        "   push   %edi;"
        "   push   %esi;"
"   push   %ebx;"
"   mov    0x2c(%esp),%ebp;"
"   mov    0x28(%esp),%edi;"
"   mov    0x24(%esp),%esi;"
"   mov    0x20(%esp),%edx;"
"   mov    0x1c(%esp),%ecx;"
"   mov    0x18(%esp),%ebx;"
"   mov    0x14(%esp),%eax;"
"   int    $0x80;"
"   pop    %ebx;"
"   pop    %esi;"
"   pop    %edi;"
"   pop    %ebp;"
"   cmp    $0xfffff001,%eax;"
"   jae    __syscall_error;"
"   ret;"    
"__syscall_error:   neg    %eax;"
"   mov    %gs:0x0,%ecx;"
"   mov    %eax,-0x18(%ecx);"
"   mov    $0xffffffff,%eax;"
"   ret;"    
#endif
);

void _start(void)
{
    static char const msg[] = "\033[33;1mThis is _start:" STR_LINE(__LINE__) "\e[0m\n";
    syscall(SYS_write, STDOUT_FILENO, msg, sizeof(msg));
    syscall(SYS_exit, 0);
}

void _init(void)
{
    static char const msg[] = "\032[33;1mThis is _init:" STR_LINE(__LINE__) "\e[0m\n";
    syscall(SYS_write, STDOUT_FILENO, msg, sizeof(msg));
}

void _fini(void)
{
    static char const msg[] = "\032[33;1mThis is _fini:" STR_LINE(__LINE__) "\e[0m\n\n\n";
    syscall(SYS_write, STDOUT_FILENO, msg, sizeof(msg));
}

int my_add(int a, int b)
{
    printf("\e[34;1mcall function %s [%s:%d]\e[0m\n", THIS_FILE, __func__, __LINE__);
    return a + b;
}
